package cn.edu.njnu.opengmpback.Modeling.service;


import cn.edu.njnu.opengmpback.Modeling.dao.LogicMaterialDao;
import cn.edu.njnu.opengmpback.Modeling.dao.LogicModelDao;
import cn.edu.njnu.opengmpback.Modeling.dao.ProjectDao;
import cn.edu.njnu.opengmpback.Modeling.entity.*;
import cn.edu.njnu.opengmpback.Modeling.entity.dto.*;
import cn.edu.njnu.opengmpback.common.utils.CommonService;
import cn.edu.njnu.opengmpback.common.utils.JsonResult;
import cn.edu.njnu.opengmpback.common.utils.ResultUtils;
import cn.edu.njnu.opengmpback.resource.dao.UserDataDao;
import cn.edu.njnu.opengmpback.user.dao.UserDao;
import cn.edu.njnu.opengmpback.user.entity.UserEntity;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.xml.transform.Result;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@Service
@Slf4j
public class LogicModelService {

    @Value("${dataStoreDir}")
    private String dataStoreDir;

    @Value("${logicModelUploadDir}")
    private String logicModelUploadDir;

    @Value("${logicMaterialUploadDir}")
    private String logicMaterialUploadDir;

    @Autowired
    LogicModelDao logicModelDao;

    @Autowired
    LogicMaterialDao logicMaterialDao;

    @Autowired
    UserDao userDao;

    @Autowired
    ProjectDao projectDao;
    @Autowired
    private CommonService commonService;

    public JsonResult createLogicModel(CreateLogicModelDTO createLogicModelDTO, MultipartFile imgFile, String userId) {
        try {
            Optional<Project> projectDB = projectDao.findById(createLogicModelDTO.getProjectId());
            if ( !projectDB.isPresent()) {
                return ResultUtils.error(-1,"项目不存在");
            }

            UserEntity user = userDao.findByUserId(userId);
            //从userdao中查找创建者信息并填充到logicModel中
            LogicModel logicModel = new LogicModel();
            logicModel.setCreatorId(user.getUserId());
            logicModel.setCreatorName(user.getName());
            logicModel.setCreatorEmail(user.getEmail());

            //将createLogicModelDTO属性拷贝到logicModel对象中
            BeanUtils.copyProperties(createLogicModelDTO, logicModel);
            if(logicModel.getLogicData() == null) {
                logicModel.setLogicData("");
            }

            File folder = new File(logicModelUploadDir);
            //定义允许的图片类型
            List<String> allowedContentTypes = Arrays.asList(
                    MediaType.IMAGE_JPEG_VALUE,
                    MediaType.IMAGE_PNG_VALUE,
                    MediaType.IMAGE_GIF_VALUE
            );

            //判断文件类型
            if (!allowedContentTypes.contains(imgFile.getContentType())) {
                return ResultUtils.error(-1,"封面文件类型不允许");
            }

            //生成封面图文件名并保存到指定目录
            if (imgFile.isEmpty()) {
                logicModel.setModelWebAddress("");
            } else {
                String modelFileName = imgFile.getOriginalFilename();
                String modelFileExtName = FileNameUtil.extName(modelFileName);
                String modelFileNewName = IdUtil.objectId()+"."+modelFileExtName;
                File saveImageFile = new File(folder, modelFileNewName);
                imgFile.transferTo(saveImageFile);
                logicModel.setModelStoreName(modelFileNewName);
                logicModel.setModelWebAddress("/store/logicModelFile/"+modelFileNewName);
                logicModel.setModelRelativePath("/logicModelFile/"+modelFileNewName);
            }

            logicModelDao.save(logicModel);
            //项目绑定逻辑建模Id
            Project project = projectDB.get();
            List<String> logicModelIdList = project.getLogicModelIdList();
            logicModelIdList.add(logicModel.getId());
            project.setLogicModelIdList(logicModelIdList);
            projectDao.save(project);
            return ResultUtils.success(logicModel);

        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtils.error(-1,"创建逻辑模型失败");
        }
    }

    public JsonResult openLogicModel(String logicModelId) {
        try{
            Optional<LogicModel> logicModelDB = logicModelDao.findById(logicModelId);
            if(!logicModelDB.isPresent()) {
                return ResultUtils.error(-1,"项目不存在");
            }
            LogicModel logicModel = logicModelDB.get();
            return ResultUtils.success(logicModel);
        }catch (Exception e) {
            e.printStackTrace();
            return ResultUtils.error(-1,"打开逻辑建模失败");
        }
    }

    public JsonResult getLogicModel(String projectId) {
        try {
            LogicModel logicModel = logicModelDao.findByProjectId(projectId);
            return ResultUtils.success(logicModel);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtils.error(-1,"获取逻辑模型失败");
        }
    }

    public JsonResult searchLogicModelList(LogicModelPageDTO logicModelFindDTO){
        try{
            Pageable pageable = commonService.getLogicModelPageable(logicModelFindDTO);
            Page<LogicModelItems> re = logicModelDao.findAllByProjectIdAndNameLikeIgnoreCase(logicModelFindDTO.getProjectId(), logicModelFindDTO.getSearchText(), pageable);
            return ResultUtils.success(re);
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResultUtils.error(-1,"项目列表获取失败");
        }
    }

    public JsonResult searchAllLogicModelList(LogicModelPageDTO logicModelFindDTO){
        try{
            Pageable pageable = commonService.getLogicModelPageable(logicModelFindDTO);
            Page<LogicModelItems> re = logicModelDao.findAllByNameLikeIgnoreCase(logicModelFindDTO.getSearchText(), pageable);
            return ResultUtils.success(re);
        }catch (Exception e){
            log.error(e.getMessage());
            return ResultUtils.error(-1,"项目列表获取失败");
        }
    }

    public JsonResult updateLogicModel(String logicModelId, CreateLogicModelDTO createLogicModelDTO, MultipartFile imgFile) throws IOException {
        Optional<LogicModel> logicModelDB = logicModelDao.findById(logicModelId);
        if(!logicModelDB.isPresent()) {
            return ResultUtils.error(-1, "项目不存在");
        }
        LogicModel logicModel = logicModelDB.get();
        if(createLogicModelDTO.getName() != null) {
            logicModel.setName(createLogicModelDTO.getName());
        }
        if(createLogicModelDTO.getDescription() != null) {
            logicModel.setDescription(createLogicModelDTO.getDescription());
        }
        if(createLogicModelDTO.getLogicData() != null) {
            logicModel.setLogicData(createLogicModelDTO.getLogicData());
        }

        //定义允许的图片类型
        List<String> allowedContentTypes = Arrays.asList(
                MediaType.IMAGE_JPEG_VALUE,
                MediaType.IMAGE_PNG_VALUE,
                MediaType.IMAGE_GIF_VALUE
        );

        //判断文件类型
        if (!allowedContentTypes.contains(imgFile.getContentType())) {
            return ResultUtils.error(-1,"封面文件类型不允许");
        }

        //图像
        if (imgFile.isEmpty()) {
            logicModel.setModelWebAddress("");
        } else {
            File folder = new File(logicModelUploadDir);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }

            //删除源文件
            String filePath = dataStoreDir + logicModel.getModelRelativePath();
            File file = new File(filePath);

            if (file.exists()) {
                FileUtil.del(filePath);
                System.out.println(filePath+"文件删除成功");
            } else {
                System.out.println("文件路径不存在");
            }

            //将文件保存到指定位置
            String modelFileName = imgFile.getOriginalFilename();
            String modelFileExtName = FileNameUtil.extName(modelFileName);
            String modelFileNewName = IdUtil.objectId()+"."+modelFileExtName;
            File saveImageFile = new File(folder, modelFileNewName);
            imgFile.transferTo(saveImageFile);
            logicModel.setModelStoreName(modelFileNewName);
            logicModel.setModelWebAddress("/store/logicModelFile/"+modelFileNewName);
            logicModel.setModelRelativePath("/logicModelFile/"+modelFileNewName);
        }
        logicModelDao.save(logicModel);
        return ResultUtils.success("更新成功");
    }

    public JsonResult deleteLogicModel(String logicModelId) {
        Optional<LogicModel> logicModelDB = logicModelDao.findById(logicModelId);
        if(!logicModelDB.isPresent()) {
            return ResultUtils.error(-1,"项目不存在");
        }
        LogicModel logicModel = logicModelDB.get();
        logicModelDao.deleteById(logicModelId);
        Project project = projectDao.findById(logicModel.getProjectId()).get();
        project.getLogicModelIdList().remove(logicModelId);
        projectDao.save(project);
        return ResultUtils.success("删除成功");
    }

    public JsonResult createMaterial(CreateLogicMaterialDTO createLogicMaterialDTO, MultipartFile imgFile, String userId){
        try{
            LogicMaterial logicMaterial = new LogicMaterial();
            BeanUtils.copyProperties(createLogicMaterialDTO, logicMaterial);

            //图像
            if (imgFile.isEmpty()) {
                logicMaterial.setMaterialWebAddress("");
            }else {
                File folder = new File(logicMaterialUploadDir);
                if (!folder.isDirectory()) {
                    folder.mkdirs();
                }

                //将文件保存到指定位置
                String materialFileName = imgFile.getOriginalFilename();;
                String materialFileExtName = FileNameUtil.extName(materialFileName);
                String materialFileNewName = IdUtil.objectId()+"."+materialFileExtName;
                File saveImageFile = new File(folder, materialFileNewName);
                imgFile.transferTo(saveImageFile);
                logicMaterial.setMaterialStoreName(materialFileNewName);
                logicMaterial.setMaterialWebAddress("/store/logicMaterialFile/"+materialFileNewName);
                logicMaterial.setMaterialRelativePath("/logicMaterialFile/"+materialFileNewName);
            }
            UserEntity user = userDao.findByUserId(userId);
            logicMaterial.setCreatorId(user.getUserId());
            logicMaterial.setCreatorName(user.getName());
            logicMaterial.setCreatorEmail(user.getEmail());
            logicMaterialDao.save(logicMaterial);

            return ResultUtils.success("创建模型条目成功！");
        }catch (Exception e) {
            log.error(e.getMessage());
            return ResultUtils.error(-1,"创建模型条目失败！");
        }
    }

    public JsonResult searchMaterialList(LogicMaterialPageDTO logicMaterialPageDTO){
        try{
            Pageable pageable = commonService.getLogicMaterialPageable(logicMaterialPageDTO);
            String type = logicMaterialPageDTO.getCurQueryField();
            Page<LogicMaterial> re;
            if(type.equals("name")){
                re = logicMaterialDao.findAllByNameLikeIgnoreCase(logicMaterialPageDTO.getSearchText(), pageable);
            }else {
                re = logicMaterialDao.findAllByDescriptionLikeIgnoreCase(logicMaterialPageDTO.getSearchText(), pageable);
            }
            return ResultUtils.success(re);
        }catch (Exception e) {
            log.error(e.getMessage());
            return ResultUtils.error(-1,"项目列表获取失败！");
        }
    }

    public JsonResult getMaterialById(String materialId){
        try{
            Optional<LogicMaterial> logicMaterialDB = logicMaterialDao.findById(materialId);
            if(!logicMaterialDB.isPresent()) {
                return ResultUtils.error(-1,"项目不存在！");
            }
            LogicMaterial logicMaterial = logicMaterialDB.get();
            return ResultUtils.success(logicMaterial);
        }catch (Exception e) {
            log.error(e.getMessage());
            return ResultUtils.error(-1,"项目信息获取失败！");
        }
    }

    public JsonResult deleteMaterial(String materialId){
        try{
            LogicMaterial logicMaterialDB = logicMaterialDao.findById(materialId).get();

            String filePath = logicMaterialUploadDir + "/" + logicMaterialDB.getMaterialStoreName();
            FileUtil.del(filePath);

            logicMaterialDao.deleteById(materialId);
            return ResultUtils.success("删除资源数据成功！");
        }catch (Exception e) {
            log.error(e.getMessage());
            return ResultUtils.error(-1,"删除数据资源失败！");
        }
    }
}
